import re
from MultiDict import OrderedMultiDict

"""Module to analyze filenames into pieces
    Splits a filename into meaningful pieces for the database and user
    
    
    TO DO:
        Subgroup is currently assumed to be the first value encapsulated
"""
# This dict contains key/regex pairs to parse encapsulate content
# These are recursively checked and should thus be in order of importance
# The regex are compiled non case-sensitive
re_encap_dict = {
           "resolution": r"(720p|1080p|1280x720|1920x1080|480p|640x480|848x480|1440x1080)",
           "10bit": r"(10bit|Hi10P|Hi10)",
           "v-codec": r"(x264|h264|xvid|MPEG2)",
           "a-codec": r"(AAC|FLAC|DTS-ES|DTS)",
           "release": r"(TV|Blu-Ray|BD|Bluray|DVD)",
           "container": r"(MP4|MKV|AVI|OGM)",
           "device": r"(PS3|XBOX|iPad|Android|iPhone|Ipod)",
           "crc": r"([0-9A-F]{8})",
           "final": r"(FINAL|END)",
           "date": r"([0-9]{4})",
           }
compil_encap_dict = {}
for key, item in re_encap_dict.iteritems():
    compil_encap_dict[key] = re.compile(item, re.IGNORECASE|re.UNICODE)

class Analyzer(object, OrderedMultiDict):
    """Analyzer for filenames and other general text
    for detecting parts in the string. Stuff like
    subgroup, anime name, episode, version, quality,
    filetype and others."""
    _re_encapsulates = re.compile(r"(\[.*?\]|\(.*?\))")
    _re_episode = re.compile(r"(?<=[_ .])(?<!Vol )(?<!PV )(?:E)?(?P<episode>[0-9]{1,3})(?!-[0-9]+)(?:v(?P<version>[0-9]+))?(?P<end>(?=[_ .\-\[]))?(?(end).|$)")
    _re_title = re.compile(r"[_.]")
    _re_extension = re.compile(r".*\." + re_encap_dict['container'], re.IGNORECASE)
    def __init__(self, text=None):
        object.__init__(self)
        OrderedMultiDict.__init__(self)
        if (text != None):
            self.parse(text)
    def parse(self, text):
        # First parse encapsulates
        # Then parse episode
        # Then anime title
        text = self._parse_extension(text)
        print text
        text = self._parse_encapsulate(text)
        print text
        text = self._parse_episode(text)
        print text
        text = self._parse_idiots(text)
        print text
        self._parse_title(text)
    def _parse_extension(self, text):
        result = self._re_extension.search(text)
        if (result):
            self["extension"] = result.group(1)
            return text[:result.start(1) - 1] + text[result.end(1):]
        else:
            return text
    def _parse_encapsulate(self, text):
        """Subject the encapsulates"""
        result = text
        index_check = 0
        for match in self._re_encapsulates.finditer(text):
            count = 0
            encap_content = match.group(0)
            for key, item in compil_encap_dict.iteritems():
                m = item.search(encap_content)
                if (m):
                    count += 1
                    self[key] = m.group(0)
                    encap_content = item.sub("", encap_content, count=1)
                    if (len(encap_content) == 0):
                        break
            if (count > 0):
                result = result[:match.start() - index_check] + result[match.end() - index_check:]
                index_check += match.end() - match.start()
            else:
                if ("group" not in self):
                    self["group"] = encap_content[1:-1]
                    result = result[:match.start() - index_check] + result[match.end() - index_check:]
                    index_check += match.end() - match.start()
        return result
    def _parse_episode(self, text):
        """Get the episode from text"""
        match = self._re_episode.search(text)
        if (match):
            for key, value in match.groupdict(None).iteritems():
                self[key] = value
            del self["end"]
            return text[:match.start()] + text[match.end():]
        return text
    def _parse_title(self, text):
        title = self._re_title.sub(" ", text)
        title = title.strip()
        title = title[:-1] if title[-1:] == "-" else title
        self["title"] = title.strip()
    _re_idiots = re.compile(r"(?P<group>THORA)")
    def _parse_idiots(self, text):
        """Parser for idiotic groups that can't into standards
        
        TODO:
            make this better for more idiots
        """
        result = self._re_idiots.search(text)
        if (result != None):
            for key, value in result.groupdict().iteritems():
                if (value != None):
                    self[key] = value
        return self._re_idiots.sub("", text, count=1)
    def __repr__(self):
        return OrderedMultiDict.__repr__(self)
def analyze(text):
    return Analyzer(text=text)